<?php

/**
 * storage actions.
 *
 * @package    sf_sandbox
 * @subpackage storage
 * @author     Your name here
 * @version    SVN: $Id: actions.class.php 2288 2006-10-02 15:22:13Z fabien $
 */
class storageActions extends autostorageActions
{

	public function executeView()
	{
		$this->getRequest()->setParameter('out', '1');
		$this->forward('storage', 'get');
	}
	
	/**
	 * Forces file to be downloaded. Expects `uid` parameter in request
	 */
	public function executeGet()
	{
		/* @var $storage Storage */
	    $uname = strip_tags($this->getRequestParameter('uid', ''));
	    $output = $this->hasRequestParameter('out');
	    
	    $c = new Criteria();
	    $c->add(StoragePeer::UNAME, $uname);
	    $storage = StoragePeer::doSelectOne($c);
	    $this->forward404Unless($storage);
	    
	    // Check if file is allowed for view/download
	    if( !$this->checkPermissions($storage, Storage::PERM_READ) )
	    {
	    	return $this->redirect('user/denied?what=storage');
	    }
	   
        if( !file_exists(Storage::getPathToStorage() . $storage->getUname()) )
        {
            return $this->forward404();
        }
        
        // Need to output to browser
        if( $output )
        {
        	// Check if file is allowed to be sent to browser
        	if( !$storage->allowToOutput() )
        	{
        		debugvar('MIME ' . $storage->getMimeType() . ' is denied to be sent to browser!');
        		return $this->redirect('storage/outputdenied?uid=' . $uname);
        	}
        	
            $this->prepareHeaders($storage, 'I');
        }else
        {
            $this->prepareHeaders($storage, 'D');
        }
        
        readfile(Storage::getPathToStorage() . $storage->getUname());
        return sfView::NONE;
	}
	
	
	/**
	 * Returns whether current user could perform action on Storage object
	 * 
	 * @param Storage $storage
	 * @param integer $actionToCheck
	 * @return boolean
	 */
	protected function checkPermissions($storage, $actionToCheck)
	{
		if( get_user_id() > 0 )
		{
			return true;
		}
		
		return false;
	}
	
	/**
	 * Sends headers to browser needed for file download/display
	 * 
	 * @param Storage $storage
	 * @param string $action D to Download, I to send to Input
	 */
	protected function prepareHeaders($storage, $action = 'D')
	{
		switch( $action )
		{
			case 'I':
                //We send to a browser
                header('Content-Type: ' . $storage->getMimeType());
                header('Cache-Control: public, must-revalidate, max-age=0'); // HTTP/1.1
                header('Pragma: public');
                header('Expires: Sat, 26 Jul 1997 05:00:00 GMT'); // Date in the past
                header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
//                header('Content-Length: '.$this->bufferlen);
                header('Content-Disposition: inline; filename="' . $storage->getRealName() . '";');

				break;
			default:
		        header('Cache-Control: public, must-revalidate, max-age=0'); // HTTP/1.1
		        header('Pragma: public');
		        header('Expires: Sat, 26 Jul 1997 05:00:00 GMT'); // Date in the past
		        header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
		        // force download dialog
		        header('Content-Type: application/force-download');
		        header('Content-Type: application/octet-stream', false);
		        header('Content-Type: application/download', false);
		        header('Content-Type: application/pdf', false);
		        // use the Content-Disposition header to supply a recommended filename
		        header('Content-Disposition: attachment; filename="' . $storage->getRealName() . '";');
		        header('Content-Transfer-Encoding: binary');
		        //header('Content-Length: '.$this->bufferlen);
				break;
		}
	}
	
	/**
	 * Save in DB and moves to storage directory
	 * 
	 * @param Storage $storage
	 */
    protected function saveStorage($storage)
	{
		$filename = $this->getRequest()->getFileName('storage[file]');
		if( $filename )
		{
            $this->checkStorageDir();
			
            // TODO: move to updateStorageFromRequest?!
            $arFile = $this->getRequest()->getFile('storage[file]');
			$storage->setMimeType($arFile['type']);
			$storage->setRealName(strip_tags($arFile['name']));
			
            $md5raw = sprintf('%d_%s', $storage->getUserId(), $storage->getRealName());
            $md5raw .= $storage->getObjId() ? '_' . $storage->getObjId() : '';
            $md5raw .= $storage->getObjType() ? '_' . $storage->getObjType() : ''; 			
			$storage->setUname(md5($md5raw));
			$storage->setMd5(md5_file($arFile['tmp_name']));
			$storage->setFileSize($arFile['size']);
            
			$this->getRequest()->moveFile('storage[file]', Storage::getPathToStorage() . $storage->getUname());
            
		}
//		debugvar($storage, 'Storage to save:');
//		debugvar($arFile, 'File to save:');
//		exit('saving file....');
        $storage->save();
	}
	
	protected function checkStorageDir()
	{
		debugvar('Checking if directory for storage exists: ' . Storage::getPathToStorage());
		// Tries to create directory for storage if not exists
        if( !is_dir(Storage::getPathToStorage()) )
        {
        	umask(0);
            if( !mkdir(Storage::getPathToStorage(), 0777, true) )
            {
                throw new Exception('Could not create directory for storage!');
            }
        }
	}
	
	/**
	 * Retrieves from DB or returns new Storage object
	 * 
	 * @param $id
	 * @return Storage
	 */
	protected function getStorageOrCreate($id = 'id')
	{
		/* @var $storage Storage */

        $storage = parent::getStorageOrCreate($id);
        
        // Set ownership if new file
        if( $storage->getUserId() < 1 )
        {
            $storage->setUserId(get_user_id());
        }
        $storage->setCulture($this->getUser()->getCulture());
        
        return $storage;
	}
	
	public function handleErrorSave()
	{
		$id = (int)$this->getRequestParameter('id', 0);
		$this->storage = $this->getStorageOrCreate($id);
        $this->labels = $this->getLabels();
        $this->setTemplate('edit');
        
        return sfView::SUCCESS;
	}
	
	public function validateSave()
	{
        $isOk = true;

        $id = (int)$this->getRequestParameter('id', 0);
        
        // Validate only newly created file
        if( $id < 1 )
        {
            $validator = new sfFileValidator();
            $validator->initialize(
                            $this->getContext()
                            , array(
                                'max_size' => 1024000
                                , 'max_size_error' => 'File too big'
                                , 'mime_types'=> Storage::getAllowedMimeTypes()
                                , 'mime_types_error' => "Not allowed file type!"
                            )
                        );
                        
            $filename = $this->getRequest()->getFileName('storage[file]');
            $file = $this->getRequest()->getFile('storage[file]');
//            debugvar($file, 'File:');
            $error = '';
            $res = $validator->execute($file, $error);
//            exit('validation...');
            if( !$res )
            {
            	$this->getRequest()->setError('storage{file}', $error);
                $isOk = false;
            }
        	
        }  // END IF ( newly uploaded file )
        
        return $isOk;
	}
	
}
